package cn.tedu.csmall.passport.service;

import cn.tedu.csmall.passport.security.JwtConst;
import cn.tedu.csmall.pojo.dto.AdminLoginDTO;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class AdminServiceImpl implements IAdminService{
    @Autowired
    AuthenticationManager authenticationManager;

    /**
     * JWT数据的密钥
     */
    @Value("${csmall.jwt.secret-key}")
    private String secretKey ;

    @Override
    public String login(AdminLoginDTO adminLoginDTO) {
        //准备被认证数据

        Authentication authentication
                 =new UsernamePasswordAuthenticationToken(
          adminLoginDTO.getUsername(),adminLoginDTO.getPassword()
        );
        //调用AuthenticationManager验证用户名与密码
        //需要用一个authentication  就要去创建一个authentication 如上:
        //执行认证,如果此过程没有抛出异常,则表示认证通过,如果认证信息有误,将抛出异常
        Authentication authenticate = authenticationManager.authenticate(authentication);





        //如果程序可以执行到此处,则表示登录成功
        //生成此用户数据的JWT
        //Claims

        User user = (User) authenticate.getPrincipal();
        System.out.println("从认证结果中获取Principal="+user.getClass().getName());


        Map<String,Object> claims = new HashMap<>();

        //写入用户名username
        claims.put(JwtConst.KEY_USERNAME,user.getUsername());
        //写入权限permissions

        // 注意：先将permissions转换成JSON字符串再写入
        claims.put(JwtConst.KEY_PERMISSIONS, JSON.toJSONString(user.getAuthorities()));

        System.out.println("即将向JWT中写入数据="+claims);

        //链式写法: 是很常见的写法
        String jwt = Jwts.builder()
                //算法部分 HS256
                .setHeaderParam(Header.CONTENT_TYPE,"HS256")
                //类型也有对应的常量
                .setHeaderParam(Header.TYPE,Header.JWT_TYPE)
                .setClaims(claims)
                //设置过期时间
                .setExpiration(new Date(System.currentTimeMillis()+5*60*1000))
                //签名
                .signWith(SignatureAlgorithm.HS256,secretKey)
                //打包生成
                .compact();
        //返回JWT数据
        return jwt;
    }
}
